home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1996 September / JCSM Shareware Collection (JCS Distribution) (September 1996).ISO / bother__ / cenvid.zip / CENVIDOS.ZIP / CMM_VS_C.DOC < prev    next >
Text File  |  1995-04-01  |  17KB  |  414 lines

  1.                     CEnvi Shareware Manual, Chapter 3:
  2.                       Cmm versus C, for C Programmers
  3.  
  4.                    
  5.                      CEnvi unregistered version 2.00
  6.                              29 March 1995
  7.  
  8.                  Copyright 1993, Nombas, All Rights Reserved.
  9.           Published by Nombas, 64 Salem Street, MEDFORD MA 02155 USA
  10.           
  11.                           VOICE (617) 391-6595
  12.                           BBS   (617) 391-3718
  13.                           FAX   (617) 391-3842
  14.  
  15.          Thank you for trying this shareware version of CEnvi from Nombas.
  16.  
  17.                           _______
  18.                      ____|__     |                (R)
  19.                   --|       |    |-------------------
  20.                     |   ____|__  |  Association of
  21.                     |  |       |_|  Shareware
  22.                     |__|   o   |    Professionals
  23.                   -----|   |   |---------------------
  24.                        |___|___|    MEMBER
  25.  
  26.  
  27.  
  28. 3.  Cmm versus C: The Cmm language for C programmers
  29.  
  30.  
  31.           This chapter is for those who already know how to program in the
  32.           C language.  This chapter describes only those elements of Cmm
  33.           that differ from standard C, and so if you don't already
  34.           understand C, then this shouldn't have much meaning for you.
  35.           Non-C programmers should instead look at the previous chapter.
  36.  
  37.           Since it is assumed that readers of this chapter are already
  38.           knowledgeable in C, only those aspects of Cmm that differ from C
  39.           are described here.  If it's not mentioned here, then assume that
  40.           Cmm behavior will be standard C.
  41.  
  42.           Deviations from C are a result of these two harmonious Cmm
  43.           directives: Convenience and Safety.  Cmm is different from C
  44.           where the change makes Cmm more convenient for small programs,
  45.           command-line code, or scripting files, or if unaltered C rules
  46.           encourage coding that is potentially unsafe.
  47.  
  48. 3.1.  C Minus Minus
  49.  
  50.           Cmm is "C minus minus" where the minuses are Type Declarations
  51.           and Pointers.  If you already know C and can remember to forget
  52.           these two aspects of C (I repeat, no Type Declarations and no
  53.           Pointers) then you know Cmm.  If you were to take C code, and
  54.           delete all the lines, code-words, and symbols that either declare
  55.           data types or explicitly point to data, then you would be left
  56.           with Cmm code; and although you would be removing bytes of source
  57.           code, you would not be removing capabilities.
  58.  
  59.           All of the details below that compare Cmm against C follow from
  60.           the general rule:
  61.             *Cmm is C minus Type Declarations and minus Pointers.
  62.  
  63. 3.2.  Data Types
  64.  
  65.           The only recognized data types are Float, Long, and Byte.  The
  66.           words "Float", "Long", and "Byte" do not appear in Cmm source
  67.           code; instead, the data types are determined by context.  For
  68.           instance 6 is a Long, 6.6 is a Float, and '6' is a Byte.  Byte is
  69.           unsigned, and the other types are signed.
  70.  
  71. 3.3.  Automatic Type Declaration
  72.  
  73.           There are no type declarators and no type casting.  Types are
  74.           determined from context.  If the code says "i=6" then i is a
  75.           Long, unless a previous statement has indicated otherwise.
  76.  
  77.           For instance, this C code:
  78.               int Max(int a,int b)
  79.               {
  80.                 int result;
  81.                 result = ( a < b ) ? b : a ;
  82.                 return result;
  83.               }
  84.           could become this Cmm code:
  85.               Max(a,b)
  86.               {
  87.                 result = ( a < b ) ? b : a ;
  88.                 return result;
  89.               }
  90.  
  91. 3.4.  Array Representation
  92.  
  93.           Arrays are used in Cmm much like they are in C, except that they
  94.           are stored differently: a first-order array (e.g., a string) is
  95.           stored in consecutive bytes in memory, but arrays of arrays are
  96.           not in consecutive memory locations.  The C declaration "char
  97.           c[3][3];" would state that there are nine consecutive bytes in
  98.           memory.  In Cmm a similar statement such as "c[2][2] = 'A'" would
  99.           tell you that there are (at least) three arrays of characters,
  100.           and the third array of arrays has (at least) three characters in
  101.           it; and although the characters in c[0] are in consecutive bytes,
  102.           and the characters in c[1] are in consecutive bytes, the two
  103.           arrays c[0] and c[1] are not necessarily adjacent in memory.
  104.  
  105. 3.4.1   Array Arithmetic
  106.  
  107.           When one array is assigned to the other, as in:
  108.               foo = "cat";
  109.               goo = foo;
  110.           then both variables define the same array and start at the same
  111.           offset 0.  In this case, if foo[2] is changed then you will find
  112.           that goo[2] has also been changed.
  113.  
  114.           Integer addition and subtraction can also be performed on arrays.
  115.           Array addition or subtraction sets where the array is based.  By
  116.           altering the previous code segment to:
  117.               foo = "cat";
  118.               goo = foo + 1;
  119.           goo and foo would now be arrays containing the same data, except
  120.           that now goo is based one element further, and foo[2] is now the
  121.           same data as goo[1].
  122.  
  123.           To demonstrate:
  124.               foo = "cat";  // foo[0] is 'c', foo[1] = 'a'
  125.               goo = foo + 1;// goo[0] is 'a', goo[-1] = 'c'
  126.               goo[0] = 'u'; // goo[0] is 'u', foo[1] = 'u', foo is "cut"
  127.               goo++;        // goo[0] is 't', goo[-2] = 'c'
  128.               goo[-2] = 'b' // goo[0] is 't', foo[0] = 'b', foo is "but"
  129.  
  130. 3.4.2   Automatic Array Allocation
  131.  
  132.           Arrays are dynamic, and any index, (positive or negative) into an
  133.           array is always valid.  If an element of an array is referred to,
  134.           then the Cmm must see to it that such an element will exist.  For
  135.           instance if the first statement in the Cmm source code is "foo[4]
  136.           = 7;" then the Cmm interpreter will make an array of 5 integers
  137.           referred to by the variable foo.  If a statement further on
  138.           refers to "foo[6]" then the Cmm interpreter will grow foo, if it
  139.           has to, to ensure that the element foo[6] exists.  This works
  140.           with negative indices as well.  When you refer to foo[-10], then
  141.           foo is grown in the other direction if it needs to be, but foo[4]
  142.           will still refer to that "7" you put there earlier.  Arrays can
  143.           reach any dimension order, so that foo[6][7][34][-1][4] is a
  144.           valid value.
  145.  
  146. 3.5.  Structures
  147.  
  148.           Structures are created dynamically, and their elements are not
  149.           necessarily contiguous in memory.  When CEnvi comes across the
  150.           statement 'foo.animal = "dog"' it creates a structure element of
  151.           foo that is referred to as "animal" and is an array of
  152.           characters, and this "animal" variable is thereafter carried
  153.           around with "foo" (much like a stem variable in REXX).  The
  154.           resulting code looks very much like regular C code, except that
  155.           there is not a separate structure definition anywhere.
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.           This C code:
  166.  
  167.               struct Point {
  168.                 int Row;
  169.                 int Column;
  170.               };
  171.  
  172.               struct Square {
  173.                 struct Point BottomLeft;
  174.                 struct Point TopRight;
  175.               };
  176.  
  177.               void main()
  178.               {
  179.                 struct Square sq;
  180.                 int Area;
  181.                 sq.BottomLeft.Row = 1;
  182.                 sq.BottomLeft.Column = 15;
  183.                 sq.TopRight.Row = 82;
  184.                 sq.TopRight.Column = 120;
  185.                 Area = AreaOfASquare(sq);
  186.               }
  187.  
  188.               int AreaOfASquare(struct Square s)
  189.               {
  190.                 int width, height;
  191.                 width = s.TopRight.Column - s.BottomLeft.Column + 1;
  192.                 height = s.TopRight.Row - s.BottomLeft.Row + 1;
  193.                 return( length * height );
  194.               }
  195.  
  196.           can be changed into the equivalent Cmm code simply be removing
  197.           declaration lines, resulting in:
  198.  
  199.               main()
  200.               {
  201.                 sq.BottomLeft.Row = 1;
  202.                 sq.BottomLeft.Column = 15;
  203.                 sq.TopRight.Row = 82;
  204.                 sq.TopRight.Column = 120;
  205.                 Area = AreaOfASquare(sq);
  206.               }
  207.  
  208.               int AreaOfASquare(s)
  209.               {
  210.                 width = s.TopRight.Column - s.BottomLeft.Column + 1;
  211.                 height = s.TopRight.Row - s.BottomLeft.Row + 1;
  212.                 return( length * height );
  213.               }
  214.  
  215.           Structures can be passed, returned, and modified just as any
  216.           other variable.  Of course structures and arrays are independent,
  217.           so you could very well have the statement "foo[8].animal.forge[3]
  218.           = bil.bo".
  219.  
  220. 3.6.  Passing Variables by Reference
  221.  
  222.           By default, LValues in Cmm are passed to functions by reference,
  223.           and so if the function alters a variable then the variable in the
  224.           calling function is altered as well IF IT IS AN LVALUE.  So
  225.           instead of this C code:
  226.  
  227.               main() {
  228.                 .
  229.                 .
  230.                 .
  231.                 CQuadrupleInPlace(&i);
  232.                 .
  233.                 .
  234.                 .
  235.               }
  236.  
  237.               void CQuadrupleInPlace(int *j)
  238.               {
  239.                 *j *= 4;
  240.               }
  241.  
  242.           the Cmm version would be:
  243.  
  244.               main() {
  245.                 .
  246.                 .
  247.                 .
  248.                 QuadrupleInPlace(i);
  249.                 .
  250.                 .
  251.                 .
  252.               }
  253.  
  254.               void QuadrupleInPlace(j)
  255.               {
  256.                 j *= 4;
  257.               }
  258.  
  259.           If the rare circumstance arises that you want to pass a copy of
  260.           an LValue to a function, instead of passing the variable by
  261.           reference, then you can use the Cmm "copy-of" operator "=".
  262.           foo(=i) can be interpreted as saying "pass a value equal to i,
  263.           but not i itself"; so that "foo(=i) ... foo(j) { j *= 4; }" would
  264.           not change the value at i.
  265.  
  266.           Note that for this Cmm version, the following calls to
  267.           QuadrupleInPlace() would be valid, but no value will have changed
  268.           upon return from QuadrupleInPlace() because an LValue is not
  269.           being passed:
  270.               QuadrupleInPlace(8);
  271.               QuadrupleInPlace(i+1);
  272.               QuadrupleInPlace(=1);
  273.  
  274. 3.7.  Data Pointers(*) and Addresses(&)
  275.  
  276.           No pointers.  None.  The "*" symbol NEVER means "pointer" and the
  277.           "&" symbol never means "address".  This may at first cause
  278.           seasoned C programmers to gasp in disbelief, but it turns out to
  279.           be not such a big deal, and these two operators are seldom
  280.           missed, after considering these two rules:
  281.               1) "*var" can be replaced in all instances by "var[0]"
  282.               2) variables (if LValues) are passed by reference
  283.  
  284. 3.8.  Case Statements
  285.  
  286.           Case statements in a switch statement may be a constant, a
  287.           variable, or any other statement that can be evaluated to a
  288.           variable.  So you might see this Cmm code:
  289.  
  290.               switch(i) {
  291.                 case 4:
  292.                 case foe():
  293.                 case sqrt(foe()):
  294.                 case (PILLBOX * 3 - 2):
  295.                 default:
  296.               }
  297.  
  298. 3.9.  Initialization: Code external to functions
  299.  
  300.           All code that is not inside any function block is interpreted
  301.           before main() is called.  So the following Cmm code:
  302.  
  303.               printf("hey there ");
  304.  
  305.               main()
  306.               {
  307.                 printf("ho there ");
  308.               }
  309.  
  310.               printf("hi there ");
  311.  
  312.           would result in the output "hey there hi there ho there ".
  313.  
  314. 3.10. Unnecessary tokens
  315.  
  316.           If symbols are redundant, then they are usually unnecessary in
  317.           Cmm.  This allows for more flexibility in the non-C-trained and
  318.           also lets more code get in the tiny space available on the
  319.           command line.  Besides, I got tired of my compiler saying
  320.           "missing semi-colon"; What good is a semi-colon if it doesn't
  321.           tell the compiler anything new?  So you can have the statement
  322.           "foo()" as well as "foo();".  It certainly doesn't hurt to have
  323.           the semi-colon there, especially when it can clarify a "return;"
  324.           statement, for example, but it isn't necessary.  Similarly, "("
  325.           and ")" are often unnecessary, so you may have "while a < b a++"
  326.           as a complete statement.
  327.  
  328. 3.11. #include
  329.  
  330.           The #include statement has been enhanced for reading source
  331.           snippets from within other types of files.  So we have
  332.  
  333.               #Include <filespec,Extension,Prefix,HeaderLine,FooterLine>
  334.  
  335.           where filespec is the same as in C's #include <filespec>
  336.           statement, Extension is a file extension (such as BAT) that may
  337.           be added to the filespec (so batch files can say #include
  338.           <%0,bat>", Prefix specifies that only those lines in filespec
  339.           that begin with Prefix will be source, and HeaderLine and
  340.           FooterLine specify that source will be read only from sections of
  341.           filespec between HeaderLine and FooterLine.  If a full path is
  342.           not specified then CEnvi searches for the file in various paths
  343.           in this order:
  344.             *Search the current directory.
  345.             *If the code is run from a *.cmm source file, then search in
  346.               the source directory for the *.cmm file.
  347.             *If this is the Windows version of CEnvi, searches all the
  348.               files in the CMMPATH profile value (from WIN.INI in the
  349.               [CEnvi] section).
  350.             *Search all directories in the CMMPATH environment variable.
  351.             *Search the directory that CEnvi.exe is executed from.
  352.             *Search all directories from the PATH environment variable.
  353.  
  354.           In CEnvi a file will not be included more than once, and so if it
  355.           has already been included, a second (or third) #include statement
  356.           will have no effect.
  357.  
  358. 3.12. Macros
  359.  
  360.           Function macros are not supported.  Since speed is not of primary
  361.           importance, a macro gains little over a function call, and so any
  362.           macros may simply become functions.
  363.  
  364.           Token replacement macros ("#define NULL 0") are supported in Cmm.
  365.  
  366. 3.13. Back-quote strings
  367.  
  368.           The back-quote character (`), also known as a "back-tick" or
  369.           "grave accent", can be used in Cmm in place of a double quote (")
  370.           to specify a string where escape sequences are not to be
  371.           translated.  So, for example, here are two ways to describe the
  372.           same file name:
  373.               "c:\\autoexec.bat"  // traditional method
  374.               `c:\autoexec.bat`   // alternative method
  375.  
  376. 3.14. Converting existing C code to Cmm
  377.  
  378.           Converting existing C code to Cmm, should you choose to do so, is
  379.           mostly a process of deleting unnecessary text.  You search on
  380.           type declarations, such as "int", "float", "struct", "char",
  381.           "[]", etc... and then delete these declaration strings.  For
  382.           instance, these instances of C code (or C++ code) on the left can
  383.           be replaced by the Cmm code on the right:
  384.  
  385.                    C                               Cmm     
  386.               ----------                      -------------
  387.  
  388.               int i;    ................... i (or nothing at all)
  389.  
  390.               int foo = 3; ................ foo = 3;
  391.  
  392.               struct {    ................... /* nothing */
  393.                 int row;
  394.                 int col;
  395.               }
  396.  
  397.               char name[] = "George"; ..... name = "George";
  398.  
  399.               int go(int a,char *s,int &c)    go(a,s,c)
  400.               int zoo[] = { 1, 2, 3 }; .... zoo = { 1, 2, 3 };
  401.  
  402.           The next step in converting C to Cmm is to search for the address
  403.           and pointer operators ("*", "&").  If the '&' and '*' work
  404.           together so that the address of a variable is passed to a
  405.           function, then both of these operators become unnecessary because
  406.           Cmm passes lvars by reference.  If there are still "*" found then
  407.           they are usually referring to the zeroth value of a pointer
  408.           address, and so can be replaced with [0], as in "*foo = 4"
  409.           replaced by "foo[0] = 4".  Finally, the "->" operator for
  410.           structures must be replaced by "." either because the structure
  411.           is now being passed by referenced or because the element of the
  412.           structure is being referred to by its array index: "foo->row" may
  413.           need to become "foo[0].row".
  414.